<?php
/**
  * Musashi - A project manager for music groups and bands
  * Copyright (C) 2010 Daniel Torres
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */

/**
 *  Controls the database operations over the expertise of a given user.
 *  
 * @package com_musashi
 * @author Daniel Torres
 */
 
// Make sure we have access to this page
defined('_JEXEC') or die ('Restricted access');

jimport('joomla.application.component.model');

/**
 *  
 *  Model for all Expertise-related operations
 *  @author Daniel Torres
 */
 class MusashiModelExpertise extends JModel
 {
        
    /**
     * Array of expertise nomenclatures
     * Expertise confort is represented as a numeric value that maps into this table.
     * These are the labels displayed throughout the site for human-readable purposes.
     * 
     * IMPORTANT: If you change these values, remember that the DB will still map to
     *            numbers and not labels. Try keeping the rating as consistent as possible.
     */
    var $_confortLabels = array(
        0   =>  "Need to learn",         //"No experience",
        1   =>  "Unconfortable",         //"Ready to learn",
        2   =>  "Only if needed",        //"Need some practice",
        3   =>  "Neutral",               //"Confortable",
        4   =>  "Confortable",           //"Expert",
        5   =>  "Preferred position",    //"Master",
    );
    
    var $_musashiMemberID = null;     // The Musashi ID of the current member (as specified on the Member table)
    var $_confortCombo    = null;     // HTML markup for a confort selection combo box
    
    
    /**
     *  Obtains the member id of the current user.
     *  WARNING: It is assumed that we have a member entry!
     */
    function getMemberID()
    {
        if( $this->_musashiMemberID == null )
        {
            // Get the current user
            $user =& JFactory::getUser();
        
            // See if we have him/her
            $query = "SELECT id FROM #__Musashi_Member WHERE userId =".$user->id;
            $this->_db->setQuery($query);
            $result = $this->_db->loadObject();
            
            if( $result != null ){
                $this->_musashiMemberID = $result->id;
            }

        }
        
        return $this->_musashiMemberID;
    }
    
    /**
     *  Obtains the list of songs known by the current user.
     *  The result is provided as an array of duples of [song id, song name]
     *  @return An array of arrays of [song id, song name], or null, if no songs are known
     */
    function getKnownSongs()
    {
        $member = $this->getMemberID();
        
        if( $member != null )
        {
            // See which songs are known
            $query = "SELECT DISTINCT s.id, s.name ".
                     "FROM #__Musashi_Expertise as e INNER JOIN #__Musashi_Song as s ".
                     "ON e.idSong = s.id ".
                     "WHERE e.idMember = ".$member;
                     
            $this->_db->setQuery($query);
            $results = $this->_db->loadRowList();

            return $results;
        }
        else
        {
            return null;
        }
        
    }
    
    /**
     *  Obtains all known positions / confort-level for the song of the provided ID
     *  @return An array of arrays of positions, in the form [pos id, pos name, confort level], null if no records are found.
     */
    function getSongExpertise( $a_songID )
    {
        $member = $this->getMemberID();
        
        if( $member != null )
        {
            // See which positions are known
            $query = "SELECT p.id, p.name, e.confort ".
                     "FROM #__Musashi_Expertise as e INNER JOIN #__Musashi_Position as p ".
                     "ON e.idPosition = p.id ".
                     "WHERE e.idMember = ".$member." AND e.idSong = ".$a_songID;
                     
            $this->_db->setQuery( $query );
            
            $results = $this->_db->loadRowList();
            return $results;
            
        }
        else
        {
            return null;
        }
    }
    
    /**
     *  Returns an array with the positions registered to the song of the provided id
     *  @param a_songID The song we are interested in
     *  @return An array of duples in the form [position name, position id]
     */
    function getSongPositions( $a_songID )
    {
        $query = "SELECT p.name, p.id FROM ".
                 "#__Musashi_Position as p INNER JOIN #__Musashi_Song_Position as s ".
                 "ON p.id = s.idPosition ".
                 "WHERE s.idSong = ".$a_songID;
                 
        $this->_db->setQuery( $query );
        $results = $this->_db->loadRowList();
        
        return $results;        
    }
    
    
    /**
     *  Obtains a list of songs not known by our current member
     *  @return An array of the form [song id, song name] for songs not known by our member.
     *          Null if all songs are known.
     */
    function getUnknownSongs()
    {
        $member = $this->getMemberID();
        
        if( $member != null )
        {
            // See which positions are known
            $query = "SELECT id, name FROM #__Musashi_Song ".
                     " WHERE id NOT IN (".
                     "     SELECT DISTINCT e.idSong FROM jos_Musashi_Expertise AS e ".
                     "     INNER JOIN jos_Musashi_Song AS s ON e.idSong = s.id ".
                     "     WHERE e.idMember = ".$member.")".
                     " ORDER BY name";
                     
            $this->_db->setQuery( $query );

            $results = $this->_db->loadRowList();
            return $results;
        }
        else
        {
            return null;
        }        
    }
    
    /**
     *  Adds an empty registry for the current user, for the song with the provided id
     */
    function addNewSong( $songID )
    {
        // Do we have this song?
        $sql = 'SELECT idMember FROM #__Musashi_Expertise WHERE idSong = '.$songID;
        $this->_db->setQuery( $query );
        if(!$this->_db->loadObject())
        {
            // Safe to go. Grab ids for all the positions played by this song:
            $query = "SELECT idPosition FROM #__Musashi_Song_Position WHERE idSong = ".$songID;
            $this->_db->setQuery( $query );
            $pID = $this->_db->loadResultArray();
            $memberID = $this->getMemberID();
            
            // Add zero entry for each triple [user, songID, position]
            $sql = "INSERT INTO #__Musashi_Expertise (idMember,idSong,idPosition) VALUES ";
            
            foreach( $pID as $propertyID )
            {
                $sql .= sprintf("(%d,%d,%d),",$memberID,$songID,$propertyID);
            }
            
            // Finish the sql string
            $sql = substr($sql,0,-1).";";
            
            // Execute
            $this->_db->setQuery( $sql );
            return $this->_db->query();
            
        }
        else
        {
            return false;
        }
    }
    
    /**
     *  Removes a song from the user's experience table
     *  @param a_nSongID The song's index to delete
     */
    function removeSong( $a_nIndex )
    {
        // Delete all entries to Musashi_Expertise that belong to us
        $sql = 'DELETE FROM #__Musashi_Expertise WHERE idSong = '.$a_nIndex.' AND idMember = '.$this->getMemberID();
        
        // Execute
        $this->_db->setQuery( $sql );
        return $this->_db->query();
    }
    
    /**
     *  Given the provided confort level index, returns an ID
     *  @param a_nIndex
     *  @return ID label, or null if out-of-bounds
     */
    function getConfortLabel( $a_nIndex )
    {
        if( $a_nIndex < count($this->_confortLabels) )
        {
            return $this->_confortLabels[$a_nIndex];            
        }
        else
        {
            return null;
        }
    }
    
    /**
     *  Returns html markup for a combo box selection. If an ID is
     *  provided, the corresponding option is made default
     */
    function getConfortHTMLCombo( $a_selected = null )
    {
        // Speed-up things: If no selection is needed, return default
        if( $a_selected == null )
        {
            if($this->_confortCombo == null)
            {
                $this->_confortCombo = "";
                foreach( $this->_confortLabels as $key => $value )
                {
                    $this->_confortCombo .= sprintf("<option value=\"%d\">%s</option> ", $key, $value );                    
                }
                
            }
            return $this->_confortCombo;
        }
        // Otherwise, run them one by one
        else
        {
            $html = "";
            foreach( $this->_confortLabels as $key => $value )
            {
                if( $key == $a_selected ){
                    $html .= sprintf("<option value=\"%d\" SELECTED >%s</option> ", $key, $value );                    
                } else {
                    $html .= sprintf("<option value=\"%d\">%s</option> ", $key, $value );                    
                }
                
            }
            
            return $html;
            
        }
    }
    
    /**
     *  Updates the song expertise of the current user, by looking at the
     *  data provided by the expertise view
     */
    function updateSongExpertise()
    {
        // We need the following information
        $songID = JRequest::getInt('songid');
        $posCnt = JRequest::getInt('posCount');
        $userID = $this->getMemberID();
        $pos    = $_POST['pos'];
        $val    = $_POST['val'];
                
        // Create a query to add/update the information
        $sql = "REPLACE INTO #__Musashi_Expertise (idMember,idSong,idPosition,confort) VALUES ";
        
        for( $i = 0; $i < $posCnt; $i++ )
        {
            $sql .= sprintf('(%d,%d,%d,%d)',$userID,$songID,$pos[$i],$val[$i]);
            
            if( $i == $posCnt - 1){
                $sql .= ';';
            } else {
                $sql .= ',';
            }
            
        }
        
        // Execute
        $this->_db->setQuery( $sql );
        return $this->_db->query();

    }
    
    
 }
?>
